home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i101: GNU AWK, version 2.11, Part15/16
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: cc05cd37 b9632938 7accf7ff 9b18de3a
-
- Submitted-by: "Arnold D. Robbins" <arnold@unix.cc.emory.edu>
- Posting-number: Volume 22, Issue 101
- Archive-name: gawk2.11/part15
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: ./CHANGES ./Makefile ./alloca.s ./field.c
- # ./gawk.texinfo.07 ./node.c
- # Wrapped by rsalz@litchi.bbn.com on Wed Jun 6 12:25:01 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 15 (of 16)."'
- if test -f './CHANGES' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./CHANGES'\"
- else
- echo shar: Extracting \"'./CHANGES'\" \(6927 characters\)
- sed "s/^X//" >'./CHANGES' <<'END_OF_FILE'
- XChanges from 2.11beta to 2.11.1 (production)
- X--------------------------------------------
- X
- XWent from "beta" to production status!!!
- X
- XNow flushes stdout before closing pipes or redirected files to
- Xsynchonize output.
- X
- XMS-DOS changes added in.
- X
- XSignal handler return type parameterized in Makefile and awk.h and
- Xsome lint removed. debug.c cleaned up.
- X
- XFixed FS splitting to never match null strings, per book.
- X
- XCorrection to the manual's description of FS.
- X
- XSome compilers break on char *foo = "string" + 4 so fixed version.sh and
- Xmain.c.
- X
- XChanges from 2.10beta to 2.11beta
- X---------------------------------
- X
- XThis release fixes all reported bugs that we could reproduce. Probably
- Xsome of the changes are not documented here.
- X
- XThe next release will probably not be a beta release!
- X
- XThe most important change is the addition of the -nostalgia option. :-)
- X
- XThe documentation has been improved and brought up-to-date.
- X
- XThere has been a lot of general cleaning up of the code that is not otherwise
- Xdocumented here. There has been a movement toward using standard-conforming
- Xlibrary routines and providing them (in missing.d) for systems lacking them.
- XImproved (hopefully) configuration through Makfile modifications and missing.c.
- XIn particular, straightened out confusion over vprintf #defines, declarations
- Xetc.
- X
- XDeleted RCS log comments from source, to reduce source size by about one third.
- XMost of them were horribly out-of-date, anyway.
- X
- XRenamed source files to reflect (for the most part) their contents.
- X
- XMore and improved error messages. Cleanup and fixes to yyerror().
- XString constants are not altered in input buffer, so error messages come out
- Xbetter. Fixed usage message. Make use of ANSI C strerror() function
- X(provided).
- X
- XPlugged many more memory leaks. The memory consumption is now quite
- Xreasonable over a wide range of programs.
- X
- XUses volatile declaration if STDC > 0 to avoid problems due to longjmp.
- X
- XNew -a and -e options to use awk or egrep style regexps, respectively,
- Xsince POSIX says awk should use egrep regexps. Default is -a.
- X
- XAdded -v option for setting variables before the first file is encountered.
- XVersion information now uses -V and copyleft uses -C.
- X
- XAdded a patchlevel.h file and its use for -V and -C.
- X
- XAppend_right() optimized for major improvement to programs with a *lot*
- Xof statements.
- X
- XOperator precedence has been corrected to match draft Posix.
- X
- XTightened up grammar for builtin functions so that only length
- Xmay be called without arguments or parentheses.
- X
- X/regex/ is now a normal expression that can appear in any expression
- Xcontext.
- X
- XAllow /= to begin a regexp. Allow ..[../..].. in a regexp.
- X
- XAllow empty compound statements ({}).
- X
- XMade return and next illegal outside a function and in BEGIN/END respectively.
- X
- XDivision by zero is now illegal and causes a fatal error.
- X
- XFixed exponentiation so that x ^ 0 and x ^= 0 both return 1.
- X
- XFixed do_sqrt, do_log, and do_exp to do argument/return checking and
- Xprint an error message, per the manual.
- X
- XFixed main to catch SIGSEGV to get source and data file line numbers.
- X
- XFixed yyerror to print the ^ at the beginning of the bad token, not the end.
- X
- XFix to substr() builtin: it was failing if the arguments
- Xweren't already strings.
- X
- XAdded new node value flag NUMERIC to indicate that a variable is
- Xpurely a number as opposed to type NUM which indicates that
- Xthe node's numeric value is valid. This is set in make_number(),
- Xtmp_number and r_force_number() when appropriate and used in
- Xcmp_nodes(). This fixed a bug in comparison of variables that had
- Xnumeric prefixes. The new code uses strtod() and eliminates is_a_number().
- XA simple strtod() is provided for systems lacking one. It does no
- Xoverflow checking, so could be improved.
- X
- XSimplification and efficiency improvement in force_string.
- X
- XAdded performance tweak in r_force_number().
- X
- XFixed a bug with nested loops and break/continue in functions.
- X
- XFixed inconsistency in handling of empty fields when $0 has to be rebuilt.
- XHappens to simplify rebuild_record().
- X
- XCleaned up the code associated with opening a pipe for reading. Gawk
- Xnow has its own popen routine (gawk_popen) that allocates an IOBUF
- Xand keeps track of the pid of the child process. gawk_pclose
- Xmarks the appropriate child as defunct in the right struct redirect.
- X
- XCleaned up and fixed close_redir().
- X
- XFixed an obscure bug to do with redirection. Intermingled ">" and ">>"
- Xredirects did not output in a predictable order.
- X
- XImproved handling of output bufferring: now all print[f]s redirected to a tty
- Xor pipe are flushed immediately and non-redirected output to a tty is flushed
- Xbefore the next input record is read.
- X
- XFixed a bug in get_a_record() where bcopy() could have copied over
- Xa random pointer.
- X
- XFixed a bug when RS="" and records separated by multiple blank lines.
- X
- XGot rid of SLOWIO code which was out-of-date anyway.
- X
- XFix in get_field() for case where $0 is changed and then $(n) are
- Xchanged and then $0 is used.
- X
- XFixed infinite loop on failure to open file for reading from getline.
- XNow handles redirect file open failures properly.
- X
- XFilenames such as /dev/stdin now allowed on the command line as well as
- Xin redirects.
- X
- XFixed so that gawk '$1' where $1 is a zero tests false.
- X
- XFixed parsing so that `RLENGTH -1' parses the same as `RLENGTH - 1',
- Xfor example.
- X
- XThe return from a user-defined function now defaults to the Null node.
- XThis fixes a core-dump-causing bug when the return value of a function
- Xis used and that function returns no value.
- X
- XNow catches floating point exceptions to avoid core dumps.
- X
- XBug fix for deleting elements of an array -- under some conditions, it was
- Xdeleting more than one element at a time.
- X
- XFix in AWKPATH code for running off the end of the string.
- X
- XFixed handling of precision in *printf calls. %0.2d now works properly,
- Xas does %c. [s]printf now recognizes %i and %X.
- X
- XFixed a bug in printing of very large (>240) strings.
- X
- XCleaned up erroneous behaviour for RS == "".
- X
- XAdded IGNORECASE support to index().
- X
- XSimplified and fixed newnode/freenode.
- X
- XFixed reference to $(anything) in a BEGIN block.
- X
- XEliminated use of USG rand48().
- X
- XBug fix in force_string for machines with 16-bit ints.
- X
- XReplaced use of mktemp() with tmpnam() and provided a partial implementation of
- Xthe latter for systems that don't have it.
- X
- XAdded a portability check for includes in io.c.
- X
- XMinor portability fix in alloc.c plus addition of xmalloc().
- X
- XPortability fix: on UMAX4.2, st_blksize is zero for a pipe, thus breaking
- Xiop_alloc() -- fixed.
- X
- XWorkaround for compiler bug on Sun386i in do_sprintf.
- X
- XMore and improved prototypes in awk.h.
- X
- XConsolidated C escape parsing code into one place.
- X
- Xstrict flag is now turned on only when invoked with compatability option.
- XIt now applies to fewer things.
- X
- XChanged cast of f._ptr in vprintf.c from (unsigned char *) to (char *).
- XHopefully this is right for the systems that use this code (I don't).
- X
- XSupport for pipes under MSDOS added.
- END_OF_FILE
- if test 6927 -ne `wc -c <'./CHANGES'`; then
- echo shar: \"'./CHANGES'\" unpacked with wrong size!
- fi
- # end of './CHANGES'
- fi
- if test -f './Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./Makefile'\"
- else
- echo shar: Extracting \"'./Makefile'\" \(7478 characters\)
- sed "s/^X//" >'./Makefile' <<'END_OF_FILE'
- X# Makefile for GNU Awk.
- X#
- X# Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
- X#
- X# This file is part of GAWK, the GNU implementation of the
- X# AWK Progamming Language.
- X#
- X# GAWK is free software; you can redistribute it and/or modify
- X# it under the terms of the GNU General Public License as published by
- X# the Free Software Foundation; either version 1, or (at your option)
- X# any later version.
- X#
- X# GAWK is distributed in the hope that it will be useful,
- X# but WITHOUT ANY WARRANTY; without even the implied warranty of
- X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X# GNU General Public License for more details.
- X#
- X# You should have received a copy of the GNU General Public License
- X# along with GAWK; see the file COPYING. If not, write to
- X# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- X# User tunable macros
- X
- X# CFLAGS: options to the C compiler
- X#
- X# -O optimize
- X# -g include dbx/sdb info
- X# -gg include gdb debugging info; only for GCC (deprecated)
- X# -pg include new (gmon) profiling info
- X# -p include old style profiling info (System V)
- X#
- X# To port GAWK, examine and adjust the following flags carefully.
- X# In addition, you will have to look at alloca below.
- X# The intent (eventual) is to not penalize the most-standard-conforming
- X# systems with a lot of #define's.
- X#
- X# -DBCOPY_MISSING - bcopy() et al. are missing; will replace
- X# with a #define'd memcpy() et al. -- use at
- X# your own risk (should really use a memmove())
- X# -DSPRINTF_INT - sprintf() returns int (most USG systems)
- X# -DBLKSIZE_MISSING - st_blksize missing from stat() structure
- X# (most USG systems)
- X# -DBSDSTDIO - has a BSD internally-compatible stdio
- X# -DDOPRNT_MISSING - lacks doprnt() routine
- X# -DDUP2_MISSING - lacks dup2() system call (S5Rn, n < 4)
- X# -DGCVT_MISSING - lacks gcvt() routine
- X# -DGETOPT_MISSING - lacks getopt() routine
- X# -DMEMCMP_MISSING - lacks memcmp() routine
- X# -DMEMCPY_MISSING - lacks memcpy() routine
- X# -DMEMSET_MISSING - lacks memset() routine
- X# -DRANDOM_MISSING - lacks random() routine
- X# -DSTRCASE_MISSING - lacks strcasecmp() routine
- X# -DSTRCHR_MISSING - lacks strchr() and strrchr() routines
- X# -DSTRERROR_MISSING - lacks (ANSI C) strerror() routine
- X# -DSTRTOD_MISSING - lacks strtod() routine
- X# -DTMPNAM_MISSING - lacks or deficient tmpnam() routine
- X# -DVPRINTF_MISSING - lacks vprintf and associated routines
- X# -DSIGTYPE=int - signal routines return int (default void)
- X
- X# Sun running SunOS 4.x
- XMISSING = -DSTRERROR_MISSING -DSTRCASE_MISSING
- X
- X# SGI Personal Iris (Sys V derived)
- X# MISSING = -DSPRINTF_INT -DBLKSIZE_MISSING -DSTRERROR_MISSING -DRANDOM_MISSING
- X
- X# VAX running Ultrix 3.x
- X# MISSING = -DSTRERROR_MISSING
- X
- X# A generic 4.2 BSD machine
- X# (eliminate GETOPT_MISSING for 4.3 release)
- X# (eliminate STRCASE_MISSING and TMPNAM_MISSING for Tahoe release)
- X# MISSING = -DBSDSTDIO -DMEMCMP_MISSING -DMEMCPY_MISSING -DMEMSET_MISSING \
- X# -DSTRERROR_MISSING -DSTRTOD_MISSING -DVPRINTF_MISSING \
- X# -DSTRCASE_MISSING -DTMPNAM_MISSING \
- X# -DGETOPT_MISSING -DSTRCHR_MISSING -DSIGTYPE=int
- X
- X# On Amdahl UTS, a SysVr2-derived system
- X# MISSING = -DBCOPY_MISSING -DSPRINTF_INT -DRANDOM_MISSING -DSTRERROR_MISSING \
- X# -DSTRCASE_MISSING -DDUP2_MISSING # -DBLKSIZE_MISSING ??????
- X
- X# Comment out the next line if you don't have gcc.
- X# Also choose just one of -g and -O.
- XCC= gcc
- X
- XOPTIMIZE= -O -g
- XPROFILE= #-pg
- XDEBUG= #-DDEBUG #-DMEMDEBUG #-DFUNC_TRACE #-DMPROF
- XDEBUGGER= #-g -Bstatic
- XWARN= #-W -Wunused -Wimplicit -Wreturn-type -Wcomment # for gcc only
- X
- X# Parser to use on grammar -- if you don't have bison use the first one
- X#PARSER = yacc
- XPARSER = bison
- X
- X# ALLOCA
- X# Set equal to alloca.o if your system is S5 and you don't have
- X# alloca. Uncomment one of the rules below to make alloca.o from
- X# either alloca.s or alloca.c.
- XALLOCA= #alloca.o
- X
- X#
- X# With the exception of the alloca rule referred to above, you shouldn't
- X# need to customize this file below this point.
- X#
- X
- XFLAGS= $(MISSING) $(DEBUG)
- XCFLAGS= $(FLAGS) $(DEBUGGER) $(PROFILE) $(OPTIMIZE) $(WARN)
- X
- X# object files
- XAWKOBJS = main.o eval.o builtin.o msg.o debug.o io.o field.o array.o node.o \
- X version.o missing.o
- X
- XALLOBJS = $(AWKOBJS) awk.tab.o
- X
- X# GNUOBJS
- X# GNU stuff that gawk uses as library routines.
- XGNUOBJS= regex.o $(ALLOCA)
- X
- X# source and documentation files
- XSRC = main.c eval.c builtin.c msg.c \
- X debug.c io.c field.c array.c node.c missing.c
- X
- XALLSRC= $(SRC) awk.tab.c
- X
- XAWKSRC= awk.h awk.y $(ALLSRC) version.sh patchlevel.h
- X
- XGNUSRC = alloca.c alloca.s regex.c regex.h
- X
- XCOPIES = missing.d/dup2.c missing.d/gcvt.c missing.d/getopt.c \
- X missing.d/memcmp.c missing.d/memcpy.c missing.d/memset.c \
- X missing.d/random.c missing.d/strcase.c missing.d/strchr.c \
- X missing.d/strerror.c missing.d/strtod.c missing.d/tmpnam.c \
- X missing.d/vprintf.c
- X
- XSUPPORT = support/texindex.c support/texinfo.tex
- X
- XDOCS= gawk.1 gawk.texinfo
- X
- XINFOFILES= gawk-info gawk-info-1 gawk-info-2 gawk-info-3 gawk-info-4 \
- X gawk-info-5 gawk-info-6 gawk.aux gawk.cp gawk.cps gawk.fn \
- X gawk.fns gawk.ky gawk.kys gawk.pg gawk.pgs gawk.toc \
- X gawk.tp gawk.tps gawk.vr gawk.vrs
- X
- XMISC = CHANGES COPYING FUTURES Makefile PROBLEMS README
- X
- XPCSTUFF= pc.d/Makefile.pc pc.d/popen.c pc.d/popen.h
- X
- XALLDOC= gawk.dvi $(INFOFILES)
- X
- XALLFILES= $(AWKSRC) $(GNUSRC) $(COPIES) $(MISC) $(DOCS) $(ALLDOC) $(PCSTUFF) $(SUPPORT)
- X
- X# Release of gawk. There can be no leading or trailing white space here!
- XREL=2.11
- X
- X# rules to build gawk
- Xgawk: $(ALLOBJS) $(GNUOBJS)
- X $(CC) -o gawk $(CFLAGS) $(ALLOBJS) $(GNUOBJS) -lm
- X
- X$(AWKOBJS): awk.h
- X
- Xmain.o: patchlevel.h
- X
- Xawk.tab.o: awk.h awk.tab.c
- X
- Xawk.tab.c: awk.y
- X $(PARSER) -v awk.y
- X -mv -f y.tab.c awk.tab.c
- X
- Xversion.c: version.sh
- X sh version.sh $(REL) > version.c
- X
- X# Alloca: uncomment this if your system (notably System V boxen)
- X# does not have alloca in /lib/libc.a
- X#
- X#alloca.o: alloca.s
- X# /lib/cpp < alloca.s | sed '/^#/d' > t.s
- X# as t.s -o alloca.o
- X# rm t.s
- X
- X# If your machine is not supported by the assembly version of alloca.s,
- X# use the C version instead. This uses the default rules to make alloca.o.
- X#
- X#alloca.o: alloca.c
- X
- X# auxiliary rules for release maintenance
- Xlint: $(ALLSRC)
- X lint -hcbax $(FLAGS) $(ALLSRC)
- X
- Xxref:
- X cxref -c $(FLAGS) $(ALLSRC) | grep -v ' /' >xref
- X
- Xclean:
- X rm -f gawk *.o core awk.output awk.tab.c gmon.out make.out version.c
- X
- Xclobber: clean
- X rm -f $(ALLDOC) gawk.log
- X
- Xgawk.dvi: gawk.texinfo
- X tex gawk.texinfo ; texindex gawk.??
- X tex gawk.texinfo ; texindex gawk.??
- X tex gawk.texinfo
- X
- X$(INFOFILES): gawk.texinfo
- X makeinfo gawk.texinfo
- X
- Xsrcrelease: $(AWKSRC) $(GNUSRC) $(DOCS) $(MISC) $(COPIES) $(PCSTUFF) $(SUPPORT)
- X -mkdir gawk-$(REL)
- X cp -p $(AWKSRC) $(GNUSRC) $(DOCS) $(MISC) gawk-$(REL)
- X -mkdir gawk-$(REL)/missing.d
- X cp -p $(COPIES) gawk-$(REL)/missing.d
- X -mkdir gawk-$(REL)/pc.d
- X cp -p $(PCSTUFF) gawk-$(REL)/pc.d
- X -mkdir gawk-$(REL)/support
- X cp -p $(SUPPORT) gawk-$(REL)/support
- X tar -cf - gawk-$(REL) | compress > gawk-$(REL).tar.Z
- X
- Xdocrelease: $(ALLDOC)
- X -mkdir gawk-$(REL)-doc
- X cp -p $(INFOFILES) gawk.dvi gawk-$(REL)-doc
- X nroff -man gawk.1 > gawk-$(REL)-doc/gawk.1.pr
- X tar -cf - gawk-$(REL)-doc | compress > gawk-doc-$(REL).tar.Z
- X
- Xpsrelease: docrelease
- X -mkdir gawk-postscript
- X dvi2ps gawk.dvi > gawk-postscript/gawk.postscript
- X psroff -t -man gawk.1 > gawk-postscript/gawk.1.ps
- X tar -cf - gawk-postscript | compress > gawk.postscript.tar.Z
- X
- Xrelease: srcrelease docrelease psrelease
- X rm -fr gawk-postscript gawk-$(REL) gawk-$(REL)-doc
- X
- Xdiff:
- X for i in RCS/*; do rcsdiff -c -b $$i > `basename $$i ,v`.diff; done
- END_OF_FILE
- if test 7478 -ne `wc -c <'./Makefile'`; then
- echo shar: \"'./Makefile'\" unpacked with wrong size!
- fi
- # end of './Makefile'
- fi
- if test -f './alloca.s' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./alloca.s'\"
- else
- echo shar: Extracting \"'./alloca.s'\" \(8394 characters\)
- sed "s/^X//" >'./alloca.s' <<'END_OF_FILE'
- X/* `alloca' standard 4.2 subroutine for 68000's and 16000's and others.
- X Also has _setjmp and _longjmp for pyramids.
- X Copyright (C) 1985, 1986, 1988 Free Software Foundation, Inc.
- X
- XThis file is part of GNU Emacs.
- X
- XGNU Emacs is distributed in the hope that it will be useful,
- Xbut WITHOUT ANY WARRANTY. No author or distributor
- Xaccepts responsibility to anyone for the consequences of using it
- Xor for whether it serves any particular purpose or works at all,
- Xunless he says so in writing. Refer to the GNU Emacs General Public
- XLicense for full details.
- X
- XEveryone is granted permission to copy, modify and redistribute
- XGNU Emacs, but only under the conditions described in the
- XGNU Emacs General Public License. A copy of this license is
- Xsupposed to have been given to you along with GNU Emacs so you
- Xcan know your rights and responsibilities. It should be in a
- Xfile named COPYING. Among other things, the copyright notice
- Xand this notice must be preserved on all copies. */
- X
- X
- X/* Both 68000 systems I have run this on have had broken versions of alloca.
- X Also, I am told that non-berkeley systems do not have it at all.
- X So replace whatever system-provided alloca there may be
- X on all 68000 systems. */
- X
- X/* #include "config.h" */
- X
- X#ifndef HAVE_ALLOCA /* define this to use system's alloca */
- X
- X#ifndef hp9000s300
- X#ifndef mc68k
- X#ifndef m68000
- X#ifndef WICAT
- X#ifndef ns16000
- X#ifndef sequent
- X#ifndef pyr
- X#ifndef ATT3B5
- X#ifndef XENIX
- Xyou
- Xlose!!
- X#endif /* XENIX */
- X#endif /* ATT3B5 */
- X#endif /* pyr */
- X#endif /* sequent */
- X#endif /* ns16000 */
- X#endif /* WICAT */
- X#endif /* m68000 */
- X#endif /* mc68k */
- X#endif /* hp9000s300 */
- X
- X
- X#ifdef hp9000s300
- X#ifdef OLD_HP_ASSEMBLER
- X data
- X text
- X globl _alloca
- X_alloca
- X move.l (sp)+,a0 ; pop return addr from top of stack
- X move.l (sp)+,d0 ; pop size in bytes from top of stack
- X add.l #ROUND,d0 ; round size up to long word
- X and.l #MASK,d0 ; mask out lower two bits of size
- X sub.l d0,sp ; allocate by moving stack pointer
- X tst.b PROBE(sp) ; stack probe to allocate pages
- X move.l sp,d0 ; return pointer
- X add.l #-4,sp ; new top of stack
- X jmp (a0) ; not a normal return
- XMASK equ -4 ; Longword alignment
- XROUND equ 3 ; ditto
- XPROBE equ -128 ; safety buffer for C compiler scratch
- X data
- X#else /* new hp assembler syntax */
- X/*
- X The new compiler does "move.m <registers> (%sp)" to save registers,
- X so we must copy the saved registers when we mung the sp.
- X The old compiler did "move.m <register> <offset>(%a6)", which
- X gave us no trouble
- X */
- X text
- X set PROBE,-128 # safety for C frame temporaries
- X set MAXREG,10 # d2-d7, a2-a5 may have been saved
- X global _alloca
- X_alloca:
- X mov.l (%sp)+,%a0 # return addess
- X mov.l (%sp)+,%d0 # number of bytes to allocate
- X mov.l %sp,%a1 # save old sp for register copy
- X mov.l %sp,%d1 # compute new sp
- X sub.l %d0,%d1 # space requested
- X and.l &-4,%d1 # round down to longword
- X sub.l &MAXREG*4,%d1 # space for saving registers
- X mov.l %d1,%sp # save new value of sp
- X tst.b PROBE(%sp) # create pages (sigh)
- X move.w &MAXREG-1,%d0
- Xcopy_regs_loop: /* save caller's saved registers */
- X mov.l (%a1)+,(%sp)+
- X dbra %d0,copy_regs_loop
- X mov.l %sp,%d0 # return value
- X mov.l %d1,%sp
- X add.l &-4,%sp # adjust tos
- X jmp (%a0) # rts
- X#endif /* new hp assembler */
- X#else
- X#ifdef mc68k /* SGS assembler totally different */
- X file "alloca.s"
- X global alloca
- Xalloca:
- X mov.l (%sp)+,%a1 # pop return addr from top of stack
- X mov.l (%sp)+,%d0 # pop size in bytes from top of stack
- X add.l &R%1,%d0 # round size up to long word
- X and.l &-4,%d0 # mask out lower two bits of size
- X sub.l %d0,%sp # allocate by moving stack pointer
- X tst.b P%1(%sp) # stack probe to allocate pages
- X mov.l %sp,%a0 # return pointer as pointer
- X mov.l %sp,%d0 # return pointer as int to avoid disaster
- X add.l &-4,%sp # new top of stack
- X jmp (%a1) # not a normal return
- X set S%1,64 # safety factor for C compiler scratch
- X set R%1,3+S%1 # add to size for rounding
- X set P%1,-132 # probe this far below current top of stack
- X
- X#else /* not mc68k */
- X
- X#ifdef m68000
- X
- X#ifdef WICAT
- X/*
- X * Registers are saved after the corresponding link so we have to explicitly
- X * move them to the top of the stack where they are expected to be.
- X * Since we do not know how many registers were saved in the calling function
- X * we must assume the maximum possible (d2-d7,a2-a5). Hence, we end up
- X * wasting some space on the stack.
- X *
- X * The large probe (tst.b) attempts to make up for the fact that we have
- X * potentially used up the space that the caller probed for its own needs.
- X */
- X .procss m0
- X .config "68000 1"
- X .module _alloca
- XMAXREG: .const 10
- X .sect text
- X .global _alloca
- X_alloca:
- X move.l (sp)+,a1 ; pop return address
- X move.l (sp)+,d0 ; pop allocation size
- X move.l sp,d1 ; get current SP value
- X sub.l d0,d1 ; adjust to reflect required size...
- X sub.l #MAXREG*4,d1 ; ...and space needed for registers
- X and.l #-4,d1 ; backup to longword boundry
- X move.l sp,a0 ; save old SP value for register copy
- X move.l d1,sp ; set the new SP value
- X tst.b -4096(sp) ; grab an extra page (to cover caller)
- X move.l a2,d1 ; save callers register
- X move.l sp,a2
- X move.w #MAXREG-1,d0 ; # of longwords to copy
- Xloop: move.l (a0)+,(a2)+ ; copy registers...
- X dbra d0,loop ; ...til there are no more
- X move.l a2,d0 ; end of register area is addr for new space
- X move.l d1,a2 ; restore saved a2.
- X addq.l #4,sp ; caller will increment sp by 4 after return.
- X move.l d0,a0 ; return value in both a0 and d0.
- X jmp (a1)
- X .end _alloca
- X#else
- X
- X/* Some systems want the _, some do not. Win with both kinds. */
- X.globl _alloca
- X_alloca:
- X.globl alloca
- Xalloca:
- X movl sp@+,a0
- X movl a7,d0
- X subl sp@,d0
- X andl #~3,d0
- X movl d0,sp
- X tstb sp@(0) /* Make stack pages exist */
- X /* Needed on certain systems
- X that lack true demand paging */
- X addql #4,d0
- X jmp a0@
- X
- X#endif /* not WICAT */
- X#endif /* m68000 */
- X#endif /* not mc68k */
- X#endif /* not hp9000s300 */
- X
- X#ifdef ns16000
- X
- X .text
- X .align 2
- X/* Some systems want the _, some do not. Win with both kinds. */
- X.globl _alloca
- X_alloca:
- X.globl alloca
- Xalloca:
- X
- X/* Two different assembler syntaxes are used for the same code
- X on different systems. */
- X
- X#ifdef sequent
- X#define IM
- X#define REGISTER(x) x
- X#else
- X#define IM $
- X#define REGISTER(x) 0(x)
- X#endif
- X
- X/*
- X * The ns16000 is a little more difficult, need to copy regs.
- X * Also the code assumes direct linkage call sequence (no mod table crap).
- X * We have to copy registers, and therefore waste 32 bytes.
- X *
- X * Stack layout:
- X * new sp -> junk
- X * registers (copy)
- X * r0 -> new data
- X * | (orig retval)
- X * | (orig arg)
- X * old sp -> regs (orig)
- X * local data
- X * fp -> old fp
- X */
- X
- X movd tos,r1 /* pop return addr */
- X negd tos,r0 /* pop amount to allocate */
- X sprd sp,r2
- X addd r2,r0
- X bicb IM/**/3,r0 /* 4-byte align */
- X lprd sp,r0
- X adjspb IM/**/36 /* space for regs, +4 for caller to pop */
- X movmd 0(r2),4(sp),IM/**/4 /* copy regs */
- X movmd 0x10(r2),0x14(sp),IM/**/4
- X jump REGISTER(r1) /* funky return */
- X#endif /* ns16000 */
- X
- X#ifdef pyr
- X
- X.globl _alloca
- X
- X_alloca: addw $3,pr0 # add 3 (dec) to first argument
- X bicw $3,pr0 # then clear its last 2 bits
- X subw pr0,sp # subtract from SP the val in PR0
- X andw $-32,sp # keep sp aligned on multiple of 32.
- X movw sp,pr0 # ret. current SP
- X ret
- X
- X#ifdef PYRAMID_OLD /* This isn't needed in system version 4. */
- X.globl __longjmp
- X.globl _longjmp
- X.globl __setjmp
- X.globl _setjmp
- X
- X__longjmp: jump _longjmp
- X__setjmp: jump _setjmp
- X#endif
- X
- X#endif /* pyr */
- X
- X#ifdef ATT3B5
- X
- X .align 4
- X .globl alloca
- X
- Xalloca:
- X movw %ap, %r8
- X subw2 $9*4, %r8
- X movw 0(%r8), %r1 /* pc */
- X movw 4(%r8), %fp
- X movw 8(%r8), %sp
- X addw2 %r0, %sp /* make room */
- X movw %sp, %r0 /* return value */
- X jmp (%r1) /* continue... */
- X
- X#endif /* ATT3B5 */
- X
- X#ifdef XENIX
- X
- X.386
- X
- X_TEXT segment dword use32 public 'CODE'
- Xassume cs:_TEXT
- X
- X;-------------------------------------------------------------------------
- X
- Xpublic _alloca
- X_alloca proc near
- X
- X pop ecx ; return address
- X pop eax ; amount to alloc
- X add eax,3 ; round it to 32-bit boundary
- X and al,11111100B ;
- X mov edx,esp ; current sp in edx
- X sub edx,eax ; lower the stack
- X xchg esp,edx ; start of allocation in esp, old sp in edx
- X mov eax,esp ; return ptr to base in eax
- X push [edx+8] ; save poss. stored reg. values (esi,edi,ebx)
- X push [edx+4] ; on lowered stack
- X push [edx] ;
- X sub esp,4 ; allow for 'add esp, 4'
- X jmp ecx ; jump to return address
- X
- X_alloca endp
- X
- X_TEXT ends
- X
- Xend
- X
- X#endif /* XENIX */
- X
- X#endif /* not HAVE_ALLOCA */
- END_OF_FILE
- if test 8394 -ne `wc -c <'./alloca.s'`; then
- echo shar: \"'./alloca.s'\" unpacked with wrong size!
- fi
- # end of './alloca.s'
- fi
- if test -f './field.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./field.c'\"
- else
- echo shar: Extracting \"'./field.c'\" \(10555 characters\)
- sed "s/^X//" >'./field.c' <<'END_OF_FILE'
- X/*
- X * field.c - routines for dealing with fields and record parsing
- X */
- X
- X/*
- X * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
- X *
- X * This file is part of GAWK, the GNU implementation of the
- X * AWK Progamming Language.
- X *
- X * GAWK is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 1, or (at your option)
- X * any later version.
- X *
- X * GAWK is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with GAWK; see the file COPYING. If not, write to
- X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X */
- X
- X#include "awk.h"
- X
- Xextern void assoc_clear();
- Xextern int a_get_three();
- Xextern int get_rs();
- X
- Xstatic char *get_fs();
- Xstatic int re_split();
- Xstatic int parse_fields();
- Xstatic void set_element();
- X
- Xchar *line_buf = NULL; /* holds current input line */
- X
- Xstatic char *parse_extent; /* marks where to restart parse of record */
- Xstatic int parse_high_water=0; /* field number that we have parsed so far */
- Xstatic char f_empty[] = "";
- Xstatic char *save_fs = " "; /* save current value of FS when line is read,
- X * to be used in deferred parsing
- X */
- X
- X
- XNODE **fields_arr; /* array of pointers to the field nodes */
- XNODE node0; /* node for $0 which never gets free'd */
- Xint node0_valid = 1; /* $(>0) has not been changed yet */
- X
- Xvoid
- Xinit_fields()
- X{
- X emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields");
- X node0.type = Node_val;
- X node0.stref = 0;
- X node0.stptr = "";
- X node0.flags = (STR|PERM); /* never free buf */
- X fields_arr[0] = &node0;
- X}
- X
- X/*
- X * Danger! Must only be called for fields we know have just been blanked, or
- X * fields we know don't exist yet.
- X */
- X
- X/*ARGSUSED*/
- Xstatic void
- Xset_field(num, str, len, dummy)
- Xint num;
- Xchar *str;
- Xint len;
- XNODE *dummy; /* not used -- just to make interface same as set_element */
- X{
- X NODE *n;
- X int t;
- X static int nf_high_water = 0;
- X
- X if (num > nf_high_water) {
- X erealloc(fields_arr, NODE **, (num + 1) * sizeof(NODE *), "set_field");
- X nf_high_water = num;
- X }
- X /* fill in fields that don't exist */
- X for (t = parse_high_water + 1; t < num; t++)
- X fields_arr[t] = Nnull_string;
- X n = make_string(str, len);
- X (void) force_number(n);
- X fields_arr[num] = n;
- X parse_high_water = num;
- X}
- X
- X/* Someone assigned a value to $(something). Fix up $0 to be right */
- Xstatic void
- Xrebuild_record()
- X{
- X register int tlen;
- X register NODE *tmp;
- X NODE *ofs;
- X char *ops;
- X register char *cops;
- X register NODE **ptr;
- X register int ofslen;
- X
- X tlen = 0;
- X ofs = force_string(OFS_node->var_value);
- X ofslen = ofs->stlen;
- X ptr = &fields_arr[parse_high_water];
- X while (ptr > &fields_arr[0]) {
- X tmp = force_string(*ptr);
- X tlen += tmp->stlen;
- X ptr--;
- X }
- X tlen += (parse_high_water - 1) * ofslen;
- X emalloc(ops, char *, tlen + 1, "fix_fields");
- X cops = ops;
- X ops[0] = '\0';
- X for (ptr = &fields_arr[1]; ptr <= &fields_arr[parse_high_water]; ptr++) {
- X tmp = *ptr;
- X if (tmp->stlen == 1)
- X *cops++ = tmp->stptr[0];
- X else if (tmp->stlen != 0) {
- X memcpy(cops, tmp->stptr, tmp->stlen);
- X cops += tmp->stlen;
- X }
- X if (ptr != &fields_arr[parse_high_water]) {
- X if (ofslen == 1)
- X *cops++ = ofs->stptr[0];
- X else if (ofslen != 0) {
- X memcpy(cops, ofs->stptr, ofslen);
- X cops += ofslen;
- X }
- X }
- X }
- X tmp = make_string(ops, tlen);
- X free(ops);
- X deref = fields_arr[0];
- X do_deref();
- X fields_arr[0] = tmp;
- X}
- X
- X/*
- X * setup $0, but defer parsing rest of line until reference is made to $(>0)
- X * or to NF. At that point, parse only as much as necessary.
- X */
- Xvoid
- Xset_record(buf, cnt)
- Xchar *buf;
- Xint cnt;
- X{
- X register int i;
- X
- X assign_number(&NF_node->var_value, (AWKNUM)-1);
- X for (i = 1; i <= parse_high_water; i++) {
- X deref = fields_arr[i];
- X do_deref();
- X }
- X parse_high_water = 0;
- X node0_valid = 1;
- X if (buf == line_buf) {
- X deref = fields_arr[0];
- X do_deref();
- X save_fs = get_fs();
- X node0.type = Node_val;
- X node0.stptr = buf;
- X node0.stlen = cnt;
- X node0.stref = 1;
- X node0.flags = (STR|PERM); /* never free buf */
- X fields_arr[0] = &node0;
- X }
- X}
- X
- XNODE **
- Xget_field(num, assign)
- Xint num;
- Xint assign; /* this field is on the LHS of an assign */
- X{
- X int n;
- X
- X /*
- X * if requesting whole line but some other field has been altered,
- X * then the whole line must be rebuilt
- X */
- X if (num == 0 && (node0_valid == 0 || assign)) {
- X /* first, parse remainder of input record */
- X if (NF_node->var_value->numbr == -1) {
- X if (parse_high_water == 0)
- X parse_extent = node0.stptr;
- X n = parse_fields(HUGE-1, &parse_extent,
- X node0.stlen - (parse_extent - node0.stptr),
- X save_fs, set_field, (NODE *)NULL);
- X assign_number(&NF_node->var_value, (AWKNUM)n);
- X }
- X if (node0_valid == 0)
- X rebuild_record();
- X return &fields_arr[0];
- X }
- X if (num > 0 && assign)
- X node0_valid = 0;
- X if (num <= parse_high_water) /* we have already parsed this field */
- X return &fields_arr[num];
- X if (parse_high_water == 0 && num > 0) /* starting at the beginning */
- X parse_extent = fields_arr[0]->stptr;
- X /*
- X * parse up to num fields, calling set_field() for each, and saving
- X * in parse_extent the point where the parse left off
- X */
- X n = parse_fields(num, &parse_extent,
- X fields_arr[0]->stlen - (parse_extent-fields_arr[0]->stptr),
- X save_fs, set_field, (NODE *)NULL);
- X if (num == HUGE-1)
- X num = n;
- X if (n < num) { /* requested field number beyond end of record;
- X * set_field will just extend the number of fields,
- X * with empty fields
- X */
- X set_field(num, f_empty, 0, (NODE *) NULL);
- X /*
- X * if this field is onthe LHS of an assignment, then we want to
- X * set NF to this value, below
- X */
- X if (assign)
- X n = num;
- X }
- X /*
- X * if we reached the end of the record, set NF to the number of fields
- X * so far. Note that num might actually refer to a field that
- X * is beyond the end of the record, but we won't set NF to that value at
- X * this point, since this is only a reference to the field and NF
- X * only gets set if the field is assigned to -- in this case n has
- X * been set to num above
- X */
- X if (*parse_extent == '\0')
- X assign_number(&NF_node->var_value, (AWKNUM)n);
- X
- X return &fields_arr[num];
- X}
- X
- X/*
- X * this is called both from get_field() and from do_split()
- X */
- Xstatic int
- Xparse_fields(up_to, buf, len, fs, set, n)
- Xint up_to; /* parse only up to this field number */
- Xchar **buf; /* on input: string to parse; on output: point to start next */
- Xint len;
- Xregister char *fs;
- Xvoid (*set) (); /* routine to set the value of the parsed field */
- XNODE *n;
- X{
- X char *s = *buf;
- X register char *field;
- X register char *scan;
- X register char *end = s + len;
- X int NF = parse_high_water;
- X char rs = get_rs();
- X
- X
- X if (up_to == HUGE)
- X NF = 0;
- X if (*fs && *(fs + 1) != '\0') { /* fs is a regexp */
- X struct re_registers reregs;
- X
- X scan = s;
- X if (rs == 0 && STREQ(FS_node->var_value->stptr, " ")) {
- X while ((*scan == '\n' || *scan == ' ' || *scan == '\t')
- X && scan < end)
- X scan++;
- X }
- X s = scan;
- X while (scan < end
- X && re_split(scan, (int)(end - scan), fs, &reregs) != -1
- X && NF < up_to) {
- X if (reregs.end[0] == 0) { /* null match */
- X scan++;
- X if (scan == end) {
- X (*set)(++NF, s, scan - s, n);
- X up_to = NF;
- X break;
- X }
- X continue;
- X }
- X (*set)(++NF, s, scan - s + reregs.start[0], n);
- X scan += reregs.end[0];
- X s = scan;
- X }
- X if (NF != up_to && scan <= end) {
- X if (!(rs == 0 && scan == end)) {
- X (*set)(++NF, scan, (int)(end - scan), n);
- X scan = end;
- X }
- X }
- X *buf = scan;
- X return (NF);
- X }
- X for (scan = s; scan < end && NF < up_to; scan++) {
- X /*
- X * special case: fs is single space, strip leading
- X * whitespace
- X */
- X if (*fs == ' ') {
- X while ((*scan == ' ' || *scan == '\t') && scan < end)
- X scan++;
- X if (scan >= end)
- X break;
- X }
- X field = scan;
- X if (*fs == ' ')
- X while (*scan != ' ' && *scan != '\t' && scan < end)
- X scan++;
- X else {
- X while (*scan != *fs && scan < end)
- X scan++;
- X if (rs && scan == end-1 && *scan == *fs) {
- X (*set)(++NF, field, (int)(scan - field), n);
- X field = scan;
- X }
- X }
- X (*set)(++NF, field, (int)(scan - field), n);
- X if (scan == end)
- X break;
- X }
- X *buf = scan;
- X return NF;
- X}
- X
- Xstatic int
- Xre_split(buf, len, fs, reregsp)
- Xchar *buf, *fs;
- Xint len;
- Xstruct re_registers *reregsp;
- X{
- X typedef struct re_pattern_buffer RPAT;
- X static RPAT *rp;
- X static char *last_fs = NULL;
- X
- X if ((last_fs != NULL && !STREQ(fs, last_fs))
- X || (rp && ! strict && ((IGNORECASE_node->var_value->numbr != 0)
- X ^ (rp->translate != NULL))))
- X {
- X /* fs has changed or IGNORECASE has changed */
- X free(rp->buffer);
- X free(rp->fastmap);
- X free((char *) rp);
- X free(last_fs);
- X last_fs = NULL;
- X }
- X if (last_fs == NULL) { /* first time */
- X emalloc(rp, RPAT *, sizeof(RPAT), "re_split");
- X memset((char *) rp, 0, sizeof(RPAT));
- X emalloc(rp->buffer, char *, 8, "re_split");
- X rp->allocated = 8;
- X emalloc(rp->fastmap, char *, 256, "re_split");
- X emalloc(last_fs, char *, strlen(fs) + 1, "re_split");
- X (void) strcpy(last_fs, fs);
- X if (! strict && IGNORECASE_node->var_value->numbr != 0.0)
- X rp->translate = casetable;
- X else
- X rp->translate = NULL;
- X if (re_compile_pattern(fs, strlen(fs), rp) != NULL)
- X fatal("illegal regular expression for FS: `%s'", fs);
- X }
- X return re_search(rp, buf, len, 0, len, reregsp);
- X}
- X
- XNODE *
- Xdo_split(tree)
- XNODE *tree;
- X{
- X NODE *t1, *t2, *t3;
- X register char *splitc;
- X char *s;
- X NODE *n;
- X
- X if (a_get_three(tree, &t1, &t2, &t3) < 3)
- X splitc = get_fs();
- X else
- X splitc = force_string(t3)->stptr;
- X
- X n = t2;
- X if (t2->type == Node_param_list)
- X n = stack_ptr[t2->param_cnt];
- X if (n->type != Node_var && n->type != Node_var_array)
- X fatal("second argument of split is not a variable");
- X assoc_clear(n);
- X
- X tree = force_string(t1);
- X
- X s = tree->stptr;
- X return tmp_number((AWKNUM)
- X parse_fields(HUGE, &s, tree->stlen, splitc, set_element, n));
- X}
- X
- Xstatic char *
- Xget_fs()
- X{
- X register NODE *tmp;
- X static char buf[10];
- X
- X tmp = force_string(FS_node->var_value);
- X if (get_rs() == 0) {
- X if (tmp->stlen == 1) {
- X if (tmp->stptr[0] == ' ')
- X (void) strcpy(buf, "[ \n]+");
- X else
- X sprintf(buf, "[%c\n]", tmp->stptr[0]);
- X } else if (tmp->stlen == 0) {
- X buf[0] = '\n';
- X buf[1] = '\0';
- X } else
- X return tmp->stptr;
- X return buf;
- X }
- X return tmp->stptr;
- X}
- X
- Xstatic void
- Xset_element(num, s, len, n)
- Xint num;
- Xchar *s;
- Xint len;
- XNODE *n;
- X{
- X *assoc_lookup(n, tmp_number((AWKNUM) (num))) = make_string(s, len);
- X}
- END_OF_FILE
- if test 10555 -ne `wc -c <'./field.c'`; then
- echo shar: \"'./field.c'\" unpacked with wrong size!
- fi
- # end of './field.c'
- fi
- if test -f './gawk.texinfo.07' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./gawk.texinfo.07'\"
- else
- echo shar: Extracting \"'./gawk.texinfo.07'\" \(6852 characters\)
- sed "s/^X//" >'./gawk.texinfo.07' <<'END_OF_FILE'
- XConcatenating two strings means sticking them together, one after another,
- Xgiving a new string. For example, the string @samp{foo} concatenated with
- Xthe string @samp{bar} gives the string @samp{foobar}.
- X@xref{Concatenation}.@refill
- X
- X@item Conditional Expression
- XAn expression using the @samp{?:} ternary operator, such as
- X@code{@var{expr1} ? @var{expr2} : @var{expr3}}. The expression
- X@var{expr1} is evaluated; if the result is true, the value of the whole
- Xexpression is the value of @var{expr2} otherwise the value is
- X@var{expr3}. In either case, only one of @var{expr2} and @var{expr3}
- Xis evaluated. @xref{Conditional Exp}.@refill
- X
- X@item Constant Regular Expression
- XA constant regular expression is a regular expression written within
- Xslashes, such as @samp{/foo/}. This regular expression is chosen
- Xwhen you write the @code{awk} program, and cannot be changed doing
- Xits execution. @xref{Regexp Usage}.
- X
- X@item Comparison Expression
- XA relation that is either true or false, such as @code{(a < b)}.
- XComparison expressions are used in @code{if} and @code{while} statements,
- Xand in patterns to select which input records to process.
- X@xref{Comparison Ops}.@refill
- X
- X@item Curly Braces
- XThe characters @samp{@{} and @samp{@}}. Curly braces are used in
- X@code{awk} for delimiting actions, compound statements, and function
- Xbodies.@refill
- X
- X@item Data Objects
- XThese are numbers and strings of characters. Numbers are converted into
- Xstrings and vice versa, as needed. @xref{Conversion}.@refill
- X
- X@item Dynamic Regular Expression
- XA dynamic regular expression is a regular expression written as an
- Xordinary expression. It could be a string constant, such as
- X@code{"foo"}, but it may also be an expression whose value may vary.
- X@xref{Regexp Usage}.
- X
- X@item Escape Sequences
- XA special sequence of characters used for describing nonprinting
- Xcharacters, such as @samp{\n} for newline, or @samp{\033} for the ASCII
- XESC (escape) character. @xref{Constants}.
- X
- X@item Field
- XWhen @code{awk} reads an input record, it splits the record into pieces
- Xseparated by whitespace (or by a separator regexp which you can
- Xchange by setting the built-in variable @code{FS}). Such pieces are
- Xcalled fields. @xref{Records}.@refill
- X
- X@item Format
- XFormat strings are used to control the appearance of output in the
- X@code{printf} statement. Also, data conversions from numbers to strings
- Xare controlled by the format string contained in the built-in variable
- X@code{OFMT}. @xref{Control Letters}; also @pxref{Output Separators}.@refill
- X
- X@item Function
- XA specialized group of statements often used to encapsulate general
- Xor program-specific tasks. @code{awk} has a number of built-in
- Xfunctions, and also allows you to define your own. @xref{Built-in};
- Xalso @pxref{User-defined}.
- X
- X@item @code{gawk}
- XThe GNU implementation of @code{awk}.
- X
- X@item Input Record
- XA single chunk of data read in by @code{awk}. Usually, an @code{awk} input
- Xrecord consists of one line of text. @xref{Records}.@refill
- X
- X@item Keyword
- XIn the @code{awk} language, a keyword is a word that has special
- Xmeaning. Keywords are reserved and may not be used as variable names.
- X
- XThe keywords of @code{awk} are:
- X@code{if},
- X@code{else},
- X@code{while},
- X@code{do@dots{}while},
- X@code{for},
- X@code{for@dots{}in},
- X@code{break},
- X@code{continue},
- X@code{delete},
- X@code{next},
- X@code{function},
- X@code{func},
- Xand @code{exit}.@refill
- X
- X@item Lvalue
- XAn expression that can appear on the left side of an assignment
- Xoperator. In most languages, lvalues can be variables or array
- Xelements. In @code{awk}, a field designator can also be used as an
- Xlvalue.@refill
- X
- X@item Number
- XA numeric valued data object. The @code{gawk} implementation uses double
- Xprecision floating point to represent numbers.@refill
- X
- X@item Pattern
- XPatterns tell @code{awk} which input records are interesting to which
- Xrules.
- X
- XA pattern is an arbitrary conditional expression against which input is
- Xtested. If the condition is satisfied, the pattern is said to @dfn{match}
- Xthe input record. A typical pattern might compare the input record against
- Xa regular expression. @xref{Patterns}.@refill
- X
- X@item Range (of input lines)
- XA sequence of consecutive lines from the input file. A pattern
- Xcan specify ranges of input lines for @code{awk} to process, or it can
- Xspecify single lines. @xref{Patterns}.@refill
- X
- X@item Recursion
- XWhen a function calls itself, either directly or indirectly.
- XIf this isn't clear, refer to the entry for ``recursion''.
- X
- X@item Redirection
- XRedirection means performing input from other than the standard input
- Xstream, or output to other than the standard output stream.
- X
- XYou can redirect the output of the @code{print} and @code{printf} statements
- Xto a file or a system command, using the @samp{>}, @samp{>>}, and @samp{|}
- Xoperators. You can redirect input to the @code{getline} statement using
- Xthe @samp{<} and @samp{|} operators. @xref{Redirection}.@refill
- X
- X@item Regular Expression
- XSee ``regexp''.
- X
- X@item Regexp
- XShort for @dfn{regular expression}. A regexp is a pattern that denotes a
- Xset of strings, possibly an infinite set. For example, the regexp
- X@samp{R.*xp} matches any string starting with the letter @samp{R}
- Xand ending with the letters @samp{xp}. In @code{awk}, regexps are
- Xused in patterns and in conditional expressions. Regexps may contain
- Xescape sequences. @xref{Regexp}.@refill
- X
- X@item Rule
- XA segment of an @code{awk} program, that specifies how to process single
- Xinput records. A rule consists of a @dfn{pattern} and an @dfn{action}.
- X@code{awk} reads an input record; then, for each rule, if the input record
- Xsatisfies the rule's pattern, @code{awk} executes the rule's action.
- XOtherwise, the rule does nothing for that input record.@refill
- X
- X@item Side Effect
- XA side effect occurs when an expression has an effect aside from merely
- Xproducing a value. Assignment expressions, increment expressions and
- Xfunction calls have side effects. @xref{Assignment Ops}.
- X
- X@item Special File
- XA file name interpreted internally by @code{gawk}, instead of being handed
- Xdirectly to the underlying operating system. For example, @file{/dev/stdin}.
- X@xref{Special Files}.
- X
- X@item Stream Editor
- XA program that reads records from an input stream and processes them one
- Xor more at a time. This is in contrast with batch programs, which may
- Xexpect to read their input files in entirety before starting to do
- Xanything, and with interactive programs, which require input from the
- Xuser.@refill
- X
- X@item String
- XA datum consisting of a sequence of characters, such as @samp{I am a
- Xstring}. Constant strings are written with double-quotes in the
- X@code{awk} language, and may contain @dfn{escape sequences}.
- X@xref{Constants}.
- X
- X@item Whitespace
- XA sequence of blank or tab characters occurring inside an input record or a
- Xstring.@refill
- X@end table
- X
- X@node Index, , Glossary, Top
- X@unnumbered Index
- X@printindex cp
- X
- X@summarycontents
- X@contents
- X@bye
- END_OF_FILE
- if test 6852 -ne `wc -c <'./gawk.texinfo.07'`; then
- echo shar: \"'./gawk.texinfo.07'\" unpacked with wrong size!
- fi
- # end of './gawk.texinfo.07'
- fi
- if test -f './node.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'./node.c'\"
- else
- echo shar: Extracting \"'./node.c'\" \(6310 characters\)
- sed "s/^X//" >'./node.c' <<'END_OF_FILE'
- X/*
- X * node.c -- routines for node management
- X */
- X
- X/*
- X * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
- X *
- X * This file is part of GAWK, the GNU implementation of the
- X * AWK Progamming Language.
- X *
- X * GAWK is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 1, or (at your option)
- X * any later version.
- X *
- X * GAWK is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with GAWK; see the file COPYING. If not, write to
- X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X */
- X
- X#include "awk.h"
- X
- Xextern double strtod();
- X
- X/*
- X * We can't dereference a variable until after we've given it its new value.
- X * This variable points to the value we have to free up
- X */
- XNODE *deref;
- X
- XAWKNUM
- Xr_force_number(n)
- XNODE *n;
- X{
- X char *ptr;
- X
- X#ifdef DEBUG
- X if (n == NULL)
- X cant_happen();
- X if (n->type != Node_val)
- X cant_happen();
- X if(n->flags == 0)
- X cant_happen();
- X if (n->flags & NUM)
- X return n->numbr;
- X#endif
- X if (n->stlen == 0)
- X n->numbr = 0.0;
- X else if (n->stlen == 1) {
- X if (isdigit(n->stptr[0])) {
- X n->numbr = n->stptr[0] - '0';
- X n->flags |= NUMERIC;
- X } else
- X n->numbr = 0.0;
- X } else {
- X errno = 0;
- X n->numbr = (AWKNUM) strtod(n->stptr, &ptr);
- X /* the following >= should be ==, but for SunOS 3.5 strtod() */
- X if (errno == 0 && ptr >= n->stptr + n->stlen)
- X n->flags |= NUMERIC;
- X }
- X n->flags |= NUM;
- X return n->numbr;
- X}
- X
- X/*
- X * the following lookup table is used as an optimization in force_string
- X * (more complicated) variations on this theme didn't seem to pay off, but
- X * systematic testing might be in order at some point
- X */
- Xstatic char *values[] = {
- X "0",
- X "1",
- X "2",
- X "3",
- X "4",
- X "5",
- X "6",
- X "7",
- X "8",
- X "9",
- X};
- X#define NVAL (sizeof(values)/sizeof(values[0]))
- X
- XNODE *
- Xr_force_string(s)
- XNODE *s;
- X{
- X char buf[128];
- X char *fmt;
- X long num;
- X char *sp = buf;
- X
- X#ifdef DEBUG
- X if (s == NULL)
- X cant_happen();
- X if (s->type != Node_val)
- X cant_happen();
- X if (s->flags & STR)
- X return s;
- X if (!(s->flags & NUM))
- X cant_happen();
- X if (s->stref != 0)
- X cant_happen();
- X#endif
- X s->flags |= STR;
- X /* should check validity of user supplied OFMT */
- X fmt = OFMT_node->var_value->stptr;
- X if ((num = s->numbr) == s->numbr) {
- X /* integral value */
- X if (num < NVAL && num >= 0) {
- X sp = values[num];
- X s->stlen = 1;
- X } else {
- X (void) sprintf(sp, "%ld", num);
- X s->stlen = strlen(sp);
- X }
- X } else {
- X (void) sprintf(sp, fmt, s->numbr);
- X s->stlen = strlen(sp);
- X }
- X s->stref = 1;
- X emalloc(s->stptr, char *, s->stlen + 1, "force_string");
- X memcpy(s->stptr, sp, s->stlen+1);
- X return s;
- X}
- X
- X/*
- X * Duplicate a node. (For strings, "duplicate" means crank up the
- X * reference count.)
- X */
- XNODE *
- Xdupnode(n)
- XNODE *n;
- X{
- X register NODE *r;
- X
- X if (n->flags & TEMP) {
- X n->flags &= ~TEMP;
- X n->flags |= MALLOC;
- X return n;
- X }
- X if ((n->flags & (MALLOC|STR)) == (MALLOC|STR)) {
- X if (n->stref < 255)
- X n->stref++;
- X return n;
- X }
- X r = newnode(Node_illegal);
- X *r = *n;
- X r->flags &= ~(PERM|TEMP);
- X r->flags |= MALLOC;
- X if (n->type == Node_val && (n->flags & STR)) {
- X r->stref = 1;
- X emalloc(r->stptr, char *, r->stlen + 1, "dupnode");
- X memcpy(r->stptr, n->stptr, r->stlen+1);
- X }
- X return r;
- X}
- X
- X/* this allocates a node with defined numbr */
- XNODE *
- Xmake_number(x)
- XAWKNUM x;
- X{
- X register NODE *r;
- X
- X r = newnode(Node_val);
- X r->numbr = x;
- X r->flags |= (NUM|NUMERIC);
- X r->stref = 0;
- X return r;
- X}
- X
- X/*
- X * This creates temporary nodes. They go away quite quickly, so don't use
- X * them for anything important
- X */
- XNODE *
- Xtmp_number(x)
- XAWKNUM x;
- X{
- X NODE *r;
- X
- X r = make_number(x);
- X r->flags |= TEMP;
- X return r;
- X}
- X
- X/*
- X * Make a string node.
- X */
- X
- XNODE *
- Xmake_str_node(s, len, scan)
- Xchar *s;
- Xint len;
- Xint scan;
- X{
- X register NODE *r;
- X char *pf;
- X register char *pt;
- X register int c;
- X register char *end;
- X
- X r = newnode(Node_val);
- X emalloc(r->stptr, char *, len + 1, s);
- X memcpy(r->stptr, s, len);
- X r->stptr[len] = '\0';
- X end = &(r->stptr[len]);
- X
- X if (scan) { /* scan for escape sequences */
- X for (pf = pt = r->stptr; pf < end;) {
- X c = *pf++;
- X if (c == '\\') {
- X c = parse_escape(&pf);
- X if (c < 0)
- X cant_happen();
- X *pt++ = c;
- X } else
- X *pt++ = c;
- X }
- X len = pt - r->stptr;
- X erealloc(r->stptr, char *, len + 1, "make_str_node");
- X r->stptr[len] = '\0';
- X r->flags |= PERM;
- X }
- X r->stlen = len;
- X r->stref = 1;
- X r->flags |= (STR|MALLOC);
- X
- X return r;
- X}
- X
- X/* Read the warning under tmp_number */
- XNODE *
- Xtmp_string(s, len)
- Xchar *s;
- Xint len;
- X{
- X register NODE *r;
- X
- X r = make_string(s, len);
- X r->flags |= TEMP;
- X return r;
- X}
- X
- X
- X#define NODECHUNK 100
- X
- Xstatic NODE *nextfree = NULL;
- X
- XNODE *
- Xnewnode(ty)
- XNODETYPE ty;
- X{
- X NODE *it;
- X NODE *np;
- X
- X#ifdef MPROF
- X emalloc(it, NODE *, sizeof(NODE), "newnode");
- X#else
- X if (nextfree == NULL) {
- X /* get more nodes and initialize list */
- X emalloc(nextfree, NODE *, NODECHUNK * sizeof(NODE), "newnode");
- X for (np = nextfree; np < &nextfree[NODECHUNK - 1]; np++)
- X np->nextp = np + 1;
- X np->nextp = NULL;
- X }
- X /* get head of freelist */
- X it = nextfree;
- X nextfree = nextfree->nextp;
- X#endif
- X it->type = ty;
- X it->flags = MALLOC;
- X#ifdef MEMDEBUG
- X fprintf(stderr, "node: new: %0x\n", it);
- X#endif
- X return it;
- X}
- X
- Xvoid
- Xfreenode(it)
- XNODE *it;
- X{
- X#ifdef DEBUG
- X NODE *nf;
- X#endif
- X#ifdef MEMDEBUG
- X fprintf(stderr, "node: free: %0x\n", it);
- X#endif
- X#ifdef MPROF
- X free((char *) it);
- X#else
- X#ifdef DEBUG
- X for (nf = nextfree; nf; nf = nf->nextp)
- X if (nf == it)
- X fatal("attempt to free free node");
- X#endif
- X /* add it to head of freelist */
- X it->nextp = nextfree;
- X nextfree = it;
- X#endif
- X}
- X
- X#ifdef DEBUG
- Xpf()
- X{
- X NODE *nf = nextfree;
- X while (nf != NULL) {
- X fprintf(stderr, "%0x ", nf);
- X nf = nf->nextp;
- X }
- X}
- X#endif
- X
- Xvoid
- Xdo_deref()
- X{
- X if (deref == NULL)
- X return;
- X if (deref->flags & PERM) {
- X deref = 0;
- X return;
- X }
- X if ((deref->flags & MALLOC) || (deref->flags & TEMP)) {
- X deref->flags &= ~TEMP;
- X if (deref->flags & STR) {
- X if (deref->stref > 1 && deref->stref != 255) {
- X deref->stref--;
- X deref = 0;
- X return;
- X }
- X free(deref->stptr);
- X }
- X freenode(deref);
- X }
- X deref = 0;
- X}
- END_OF_FILE
- if test 6310 -ne `wc -c <'./node.c'`; then
- echo shar: \"'./node.c'\" unpacked with wrong size!
- fi
- # end of './node.c'
- fi
- echo shar: End of archive 15 \(of 16\).
- cp /dev/null ark15isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 16 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-